﻿
Namespace Aricie.DNN.Services.Url.FriendlyUrl.SimpleAPI
    ''' <summary>
    ''' Use the factory to easily create the SimpleGroupParamsRewrite you'll need when working with a SimpleRewriterProvider
    ''' </summary>
    ''' <remarks>Start the group creation by using the CreateGroup method. End the group creation by using the Create method.</remarks>
    Public NotInheritable Class SimpleGroupFluentFactory
        Implements ISimpleGroupFluentFactory

        ''' <summary>
        ''' Start your group creation
        ''' </summary>
        ''' <param name="name">Group name</param>
        ''' <param name="description">Group description</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Shared Function CreateGroup(ByVal name As String, ByVal description As String) As ISimpleGroupFluentFactory
            Return New SimpleGroupFluentFactory() With {.Result = New SimpleGroupParamsRewrite(name, description)}
        End Function

        ''' <summary>
        ''' Start your group creation
        ''' </summary>
        ''' <param name="name">Group name</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks>The group will be created with an empty description. If you want to set a description, use CreateGroup(name, description) instead</remarks>
        Public Shared Function CreateGroup(ByVal name As String) As ISimpleGroupFluentFactory
            Return CreateGroup(name, String.Empty)
        End Function

        Protected Property Result As SimpleGroupParamsRewrite

        ''' <summary>
        ''' Add a parameter to the group; this parameter will be usable by another group.
        ''' </summary>
        ''' <param name="name">Parameter name</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function AddNonExclusiveParameter(ByVal name As String) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.AddNonExclusiveParameter
            Return AddParameter(name, ParamNature.NonExclusive Or ParamNature.Mandatory)
        End Function

        ''' <summary>
        ''' Add a parameter to the group; this parameter will be optional, which means that the rewriting this groups defines will occur even if the parameter is not present.
        ''' </summary>
        ''' <param name="name">Parameter name</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function AddOptionalParameter(ByVal name As String) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.AddOptionalParameter
            Return AddParameter(name, ParamNature.Exclusive Or ParamNature.Optional)
        End Function

        ''' <summary>
        ''' Add a parameter to the group; by default this parameter will be exclusive (ie not usable by another group) and mandatory (ie the rewriting won't take place if this parameter doesn't exist in the url this group tries to rewrite)
        ''' </summary>
        ''' <param name="name">Parameter name</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function AddParameter(ByVal name As String) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.AddParameter
            Return AddParameter(name, ParamNature.Exclusive Or ParamNature.Mandatory)
        End Function

        ''' <summary>
        ''' Add a parameter to the group; you can define if this parameter is exclusive or not (ie if it will be shared between different groups) and if it is mandatory or not (ie if the rewriting takes place whether the parameter is present or not)
        ''' </summary>
        ''' <param name="name">Parameter name</param>
        ''' <param name="Flags">Parameter options: mandatory or optional, exclusive or shared</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function AddParameter(ByVal name As String, ByVal Flags As ParamNature) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.AddParameter
            Result.UrlParams.Add(UrlParam.FromSyntax(name), Flags)
            Return Me
        End Function

        ''' <summary>
        ''' When you're done defining your group, call this method to retrieve the group
        ''' </summary>
        ''' <returns>A SimpleGroupParamsRewrite</returns>
        ''' <remarks></remarks>
        Public Function Create() As SimpleGroupParamsRewrite Implements ISimpleGroupFluentFactory.Create
            Return Result
        End Function

        ''' <summary>
        ''' Sets the regular expression for the group
        ''' </summary>
        ''' <param name="regex">The regular expression for the group</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function SetRegexPattern(ByVal regex As String) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.SetRegexPattern
            Result.LookupRegexPattern = regex
            Return Me
        End Function

        ''' <summary>
        ''' Sets the rewritetype for the group
        ''' </summary>
        ''' <param name="RewriteType">The rewritetype for the group</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function SetRewriteType(ByVal RewriteType As RewriteType) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.SetRewriteType
            Result.RewriteType = RewriteType
            Return Me
        End Function

        ''' <summary>
        ''' Sets the method this group will use to rewrite its portion of the url
        ''' </summary>
        ''' <param name="Rewriter">The delegate</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks>The method used must follow the delegate signature</remarks>
        Public Function SetRewritingDelegate(ByVal Rewriter As SimpleGroupParamsRewrite.SimpleRewriteDelegate) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.SetRewritingDelegate
            Result.Rewriter = Rewriter
            Return Me
        End Function

        ''' <summary>
        ''' Sets the consumption value for the group (ie if the group declares the parameter as having been used)
        ''' </summary>
        ''' <param name="Consume">The consumption value as boolean</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function SetConsume(ByVal Consume As Boolean) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.SetConsume
            Result.Consume = Consume
            Return Me
        End Function

        ''' <summary>
        ''' Indicate if the strategy filtering must take place automatically (ie defines if the group will automatically apply the rules that may be defined at the strategy level configuration (lowercasing, character swap, etc))
        ''' </summary>
        ''' <param name="ApplyBehaviour">The value indicating if the strategy filtering must take place</param>
        ''' <returns>The factory for chaining calls</returns>
        ''' <remarks></remarks>
        Public Function SetFilter(ByVal ApplyBehaviour As Boolean) As ISimpleGroupFluentFactory Implements ISimpleGroupFluentFactory.SetFilter
            Result.ApplyBehaviour = ApplyBehaviour
            Return Me
        End Function

    End Class
End Namespace